package pl.shenlon.ga;

import java.util.Random;

public abstract class Specimen implements Comparable<Specimen> {

	public static final Random rnd;

	static {
		rnd = new Random();
	}

	public static Specimen[] shuffleSpecimens(Specimen[] specimens) {
		Specimen tmp = null;
		for (int i = 0; i < specimens.length; i++) {
			int pos = rnd.nextInt(specimens.length);
			tmp = specimens[i];
			specimens[i] = specimens[pos];
			specimens[pos] = tmp;
			tmp = null;
		}
		return specimens;
	}

	protected final Genom genom;

	// protected int id;

	private int score;

	public Specimen(Genom genom) {
		this.genom = genom.copy();
	}

	@Override
	public int compareTo(Specimen that) {
		if (that == null) {
			return 1;
		}
		return Integer.compare(this.score, that.score);
	}

	public abstract Specimen copy();

	public abstract Specimen[] crossover(double crossoverRate, Specimen other);

	@Override
	public boolean equals(Object other) {
		if (other != null && other instanceof Specimen) {
			return this.genom.equals(((Specimen) other).genom);
		}
		return false;
	}

	public Genom getGenom() {
		return genom;
	}

	public int getScore() {
		return score;
	}

	public boolean mutate(double mutationRate) {
		return genom.mutate(mutationRate);
	}

	public void setScore(int score) {
		this.score = score;
	}

	public void updateScore(int amount) {
		score += amount;
	}

	@Override
	public String toString() {
		return genom.toString();
	}
}